package model

import (
	"errors"
	"gitee.com/sansaniot/ssiot-gw-lib-comm/common/db"
	"gorm.io/gorm"
	"time"
)

type Device struct {
	ID           uint   `gorm:"primaryKey;"`
	DevSn        string `gorm:"index;type:varchar(50);comment:设备序列号"`
	CommId       string `gorm:"index;type:varchar(50);comment:唯一标识一个通讯链路的ID tcp端口号/dtuid/串口名/ip:端口"`
	CommType     string `gorm:"index;type:varchar(50);comment:通讯方式 tcp/udp/ddp/uart/ethernet"`
	Channel      string `gorm:"type:varchar(50);comment:通道名称 COM0/net"`
	ChannelParam string `gorm:"index;type:varchar(50);comment:通道参数 9600,8N1/ip:端口"`
	SlaveAddr    string `gorm:"index;type:varchar(50);comment:从机地址"`
	Protocol     string `gorm:"type:varchar(50);comment:编解码协议"`
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type CommIds map[string]Device

// FindCommIdByType 按通讯方式查找设备
func (d *Device) FindCommIdByType() (CommIds, *gorm.DB) {
	devices := make([]Device, 0)
	result := db.Db.Where(Device{CommType: d.CommType}).Find(&devices)
	commIds := make(CommIds)

	for _, d := range devices {
		commIds[d.CommId] = d
	}

	return commIds, result
}

func (d *Device) FindByCommId() ([]*Device, *gorm.DB) {
	devices := make([]*Device, 0)
	result := db.Db.Where(Device{CommId: d.CommId}).Find(&devices)
	return devices, result
}

func (d *Device) GetBySn() *gorm.DB {
	result := db.Db.Where(Device{DevSn: d.DevSn}).First(d)
	return result
}

// SaveBySn 更新配置
func (d *Device) SaveBySn() (update bool) {
	commId := d.CommId
	commType := d.CommType
	channel := d.Channel
	channelParam := d.ChannelParam
	slaveAddr := d.SlaveAddr
	protocol := d.Protocol

	result := d.GetBySn()
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		db.Db.Create(d)
		return false
	}

	db.Db.Model(d).Updates(Device{
		CommId:       commId,
		CommType:     commType,
		Channel:      channel,
		ChannelParam: channelParam,
		SlaveAddr:    slaveAddr,
		Protocol:     protocol,
	})
	return true
}

// RemoveBySn 删除配置
func (d *Device) RemoveBySn() {
	db.Db.Delete(d, Device{DevSn: d.DevSn})
}
